package com.fangda.network.udp;

import com.fangda.network.*;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.datagram.DatagramSocket;
import io.vertx.core.net.SocketAddress;
import lombok.Getter;
import lombok.Setter;

/**
 * UDP网络并不需要连接，客户端直接发送消息即可。
 * 调用send方法发送消息
 */
public class UdpNetwork extends AbstractNetwork {

    @Setter
    @Getter
    private DatagramSocket socket;

    public UdpNetwork(String id, NetworkConfig config) {
        super(id, config);
    }

    @Override
    public NetworkType getNetworkType() {
        return NetworkType.UDP;
    }

    public void startup() {
        socket.handler(res -> {
            if(config.getParser() != null) {
                config.getParser().decode(new NetworkMessage(res.data().getBytes(), socket.localAddress().toString()));
            }
        });
        socket.exceptionHandler(v -> {
            if(getCallback() != null) {
                getCallback().exceptionHandler(v);
            }
        });
        socket.listen(config.getPort(), config.getIp(), res -> {
            this.alive = res.succeeded();
            if(getCallback() != null) {
                getCallback().connectionChange(res.succeeded(), res.cause());
            }
        });
    }

    @Override
    public void shutdown() {
        if(socket != null) {
            socket.close();
            if(getCallback() != null) {
                getCallback().connectionChange(false, null);
            }
        } else {
            this.alive = false;
        }
    }

    @Override
    public void reload() {
        shutdown();
        startup();
    }

    /**
     * 发送消息
     * @param message
     * @param messageCallback
     */
    public void send(NetworkMessage message, NetworkMessageCallback messageCallback) {
        socket.send(Buffer.buffer(message.getPayload()), config.getPort(), config.getIp(), res -> {
            if(messageCallback != null) {
                messageCallback.callback(res, SocketAddress.inetSocketAddress(config.getPort(), config.getIp()));
            }
        });
    }
}
